#!/usr/bin/python

from mezoGISlib._plugins import Argument, UserPlugin
from mezoGISlib._dbtools import getGeometryExtent
from mezoGISlib import Table

from GeoTypes import OGPolygon, OGlinearRingFromSequence
import math

class hexRaster(UserPlugin):

    def __init__(self):
        UserPlugin.__init__(self, "Create Hexagonal Tesselation",
        "Create a hexagonal tesselation",
        "Create a hexagonal tesselation over an\nexisting layer of data.")
        self.arguments = {
            "input table": Argument(Argument.ttable,"the name of the original table","inputTable"),
            "geometry column": Argument(Argument.tstring,"the column that contains geometry","the_geom"),

            "new table": Argument(Argument.tstring,"the name of the table to create","outputTable"),
            "side length": Argument(Argument.tfloat,"the length of a hexagon side, in world units",0.0),
            "srid": Argument(Argument.tnumber,"the srid of the target table",-1)
        }

    def getInput(self):
        return self.arguments
 
    def launch(self, db):
        table_out = self.arguments["new table"].value
        geom_col = self.arguments["geometry column"].value
        geom_out = geom_col
        table_in = self.arguments["input table"].value
        srid = self.arguments["srid"].value

        # get hexagon co-ordinates
        s = self.arguments["side length"].value
        h = math.sin(math.radians(30)) * s
        r = math.cos(math.radians(30)) * s
        height = s + 2 * h
        row_height = s+h # the height of one row of hexagons if stacked
        width = 2 * r

        # get extent of geometry
        extent = getGeometryExtent(db, table_in, geom_col)
        geomwidth  = extent.getUpperRight().getX() - extent.getLowerLeft().getX()
        geomheight = extent.getUpperRight().getY() - extent.getLowerLeft().getY()
        translate_y = extent.getLowerLeft().getY()
        translate_x = extent.getLowerLeft().getX()

        # start output
        cursor = db.handle.cursor()

        def execute(sql):
            #print sql
            cursor.execute(sql)

        print 'creating table %s' %table_out

        execute('CREATE TABLE %s (gid serial PRIMARY KEY,"col" int, "row" int);\n' %table_out)
        execute("SELECT AddGeometryColumn('','%s','%s','%i','POLYGON',2);\n"%(table_out,geom_out,srid))

        # prepare insert row
        q = 'INSERT INTO '+table_out+'("col","row","'+geom_out+"\") VALUES ('%i','%i',%s);\n"

        step = 100 / geomheight * row_height
        percent = 0

        row = 0
        while row*row_height <= geomheight:

            self.progress(percent)
            percent += step

            col = 0

            # ident odd rows by r
            if row % 2: ident = r
            else: ident = 0
            y = row*(h+s) +  + translate_y

            while col*width <= geomwidth:
                x = col*width + ident + translate_x
                points = [(x+0,y+h),(x+r,y+0)]
                points.append( [x+width,y+h] )
                points.append( [x+width,y+h+s] )
                points.append( [x+r,y+height] )
                points.append( [x+0,y+s+h] )
                points.append( (x+0,y+h) ) # close ring
                poly = OGPolygon(srid)
                poly.append(OGlinearRingFromSequence(points))
                execute(q%(col,row,poly))

                col += 1
            row += 1

        db.handle.commit()
        cursor.close()

def register():
    return hexRaster()
    
